// Include header files for S3E (core system) and IwGx (rendering) modules

#include "IwGx.h"
#include "IwUI.h"

#include "time.h"

#include "CppSqlWrapper.h"
#include "s3eFile.h"


#define MS_PER_FRAME (1000 / 25)

// variables
enum TaskType{ Import, Export };
TaskType g_Task = Import;// default Import
const char* OUTPUT_FILE_NAME = "data.txt";
s3eFile* output_file;
bool g_Quit = false;
char* m_RootElement = "RootElement";
double m_MoneyImport = 0;
double m_MoneyExport = 0;

const char* DB_FILE_NAME = "sqlite.sdb";
SqlDatabase* dbProvider;
CIwUILayoutGrid* dataGrid;
int rowId = -1; // RowId of Item that selected in the Grid.
int indexRowId = -1; // index of Item that selected in the Grid.
bool isDelete = false;
int startItem = 0;
int pageSize = 5;
int itemCount = 0;

void AppInit();
void AppShutDown();
bool AppUpdate(int32 deltaMS);
void AppRender();
void InitDataBinding();
void UpdateDataBinding();
void InitSQLite();

// Globals UI
CIwResGroup* pResGroup;
CIwUIElement* rootElement;
CIwUIElement* DeleteDialog;
//CIwUIImage* ImageMoney;
CIwUILabel* LabelMoneyIn;
CIwUILabel* LabelMoneyOut;
CIwUILabel* LabelRemain;
CIwUILabel* LabelInput;
CIwUIButton* TaskImport;
CIwUIButton* TaskExport;
CIwUIButton* ButtonReset;
CIwUIButton* Button_Dot;
CIwUIButton* PreviousPage;
CIwUIButton* NextPage;

bool g_ClearData = false;
class CCommandHandler;
// Create singletons
CCommandHandler* pCommandHandler;
// Singleton accessor

time_t GetNow()
{
    //Get local time
    time_t curtime;
    struct tm *loctime;
    curtime = time (NULL);
    loctime = localtime (&curtime);
    return mktime(loctime);
}

void showDate()
{
	time_t day = GetNow();
	char title[64];
    strftime (title, 64, "%d %m %Y", localtime(&day));
	LabelInput->SetCaption(title);
}

char* removeRight(char* str)
	{
		int iEnd = 0;
		int i = strlen(str) -1;
		for(i ; i > 0; i--)
		{
			if(str[i] == '.')
			{
				break;
			}
			if(str[i] != '0' && iEnd == 0)
			{
				iEnd = i;
			}
		}
		// have dot (.)
		if(i > 0 && iEnd == 0)
		{
			iEnd = i - 1;
		}
		else if(iEnd == 0)
		{
			str = "0";
		}
		str[iEnd + 1] = '\0';
		return str;
	}

char* dbtostr(double d)
{
		char* result = new char[100];
		sprintf(result,"%1.2lf",d);
		removeRight(result);
		return result;
}

double strtodb(char* str)
{
	return strtod(str, NULL);
}

void readFileData()
{
	output_file = s3eFileOpen(OUTPUT_FILE_NAME, "rt");
	int32 fileSize = s3eFileGetSize( output_file );
	if(fileSize < 0)
	{
		s3eFileClose(output_file);
		return;
	}
	char* line = new char[fileSize];
	s3eFileRead(line, fileSize,1, output_file);
	s3eFileClose(output_file);
	if(fileSize > 0)
	{
		if(line[0] == '2')
			g_Task = Export;
		char* result = new char[50];
		int idx = 0;
		for(int i = 2;i<strlen(line);i++)
		{
			if(line[i] == '|')
			{
				result[idx] = '\0';
				m_MoneyImport = strtodb(result);
				delete[] result;
				char* result = new char[50];
				idx = 0;
			}
			else
			{
				result[idx++] = line[i];
			}
		}
		m_MoneyExport = strtodb(result);

		delete[] result;
	}
	delete[] line;
}

void writeFileData()
{
	char* str = new char[255];
	char* strDb;
	strcpy(str,"1|");
	if(g_Task == Export)
		strcpy(str,"2|");
	strDb = dbtostr(m_MoneyImport);
	strcat(str, strDb);
	delete[] strDb;
	strcat(str, "|");
	strDb = dbtostr(m_MoneyExport);
	strcat(str, strDb);
	delete[] strDb;
	output_file = s3eFileOpen(OUTPUT_FILE_NAME, "w");
	s3eFilePrintf(output_file, "%s\r\n", str);
	s3eFileClose(output_file);
	delete[] str;
}

void output() { // Print a blank line
	s3eFilePrintf(output_file, "\r\n");
	printf("\n");
}

void output(const char* str, ...) {
	s3eFilePrintf(output_file, "%s\r\n", str);
	printf("%s\n", str);
}


void deleteData(const int pRowId);

// -------------------------------------------------------------------------
CIwUILabel* createLabel(const char* caption, const char* style)
{
	CIwUILabel* label = new CIwUILabel();
	label->SetStyle(style);
	label->SetCaption(caption);
	return label;
}

// -------------------------------------------------------------------------
// Add data to the bottom of Grid.
void addDataItem(const int pRowId, const char* pValue, const char* pTaskType, const char* pDate)
{
	CIwUILabel* lblValue = createLabel(pValue, "LabelValue");
	CIwUILabel* lblTaskType = createLabel(pTaskType, "LabelTaskType");
	CIwUILabel* lblDate = createLabel(pDate, "LabelDate");

	char sRowid[10];
	sprintf(sRowid,"%d", pRowId);
	char* sBtnName = new char[255];
	
	CIwUILabel* lblRowId = createLabel(sRowid, "LabelRowId");
	int rowCount = dataGrid->GetNumRows();
	dataGrid->AddRow();
	dataGrid->AddElement(lblValue, 0, rowCount);
	dataGrid->AddElement(lblTaskType, 1, rowCount);
	dataGrid->AddElement(lblDate, 2, rowCount);
	dataGrid->AddElement(lblRowId, 3, rowCount);lblRowId->SetVisible(false);

	delete[] sBtnName;
}
// -------------------------------------------------------------------------
void updateDataItem(const char* pValue, const char* pTaskType, const char* pDate)
{
		CIwUIElement* parent = dataGrid->GetElement();
		CIwUILabel* lblValue = (CIwUILabel*)(parent->GetChild(indexRowId - 3));
		CIwUILabel* lblTaskType = (CIwUILabel*)(parent->GetChild(indexRowId - 2));
		CIwUILabel* lblDate = (CIwUILabel*)(parent->GetChild(indexRowId - 1));

		lblValue->SetCaption(pValue);
		lblTaskType->SetCaption(pTaskType);
		lblDate->SetCaption(pDate);
}
// -------------------------------------------------------------------------
void removeDataItem()
{
		CIwUIElement* parent = dataGrid->GetElement();
		CIwUILabel* lblValue = (CIwUILabel*)(parent->GetChild(indexRowId - 3));
		CIwUILabel* lblTaskType = (CIwUILabel*)(parent->GetChild(indexRowId - 2));
		CIwUILabel* lblDate = (CIwUILabel*)(parent->GetChild(indexRowId - 1));
		CIwUILabel* lblRowId = (CIwUILabel*)(parent->GetChild(indexRowId));// get RowId have index is 3.

		const char* srowid = lblRowId->GetCaption();
		rowId = atoi(srowid);

		deleteData(rowId);
		dataGrid->RemoveElement(lblValue);
		dataGrid->RemoveElement(lblTaskType);
		dataGrid->RemoveElement(lblDate);
		dataGrid->RemoveElement(lblRowId);

		parent->RemoveChild(lblValue);
		parent->RemoveChild(lblTaskType);
		parent->RemoveChild(lblDate);
		parent->RemoveChild(lblRowId);

		delete lblValue;
		delete lblTaskType;
		delete lblDate;
		delete lblRowId;

		dataGrid->SetSizeToSpace(true);
}
// -------------------------------------------------------------------------
// Gets all data from databse and add to Grid.
void addGridAllData()
{
	// select all order by RowId
	SqlStatement select = dbProvider->sqlQuery("select RowId, Value, TaskType, CreatedDate from DataImEx order by RowId desc;");
	if(!select.hasRow())
		return;
	do
	{
		const SqlStatement::ResultRow& row = select.currentRow();
		//addDataItem(row.getIntField("RowId"), row.getFloatField("Value"), row.getIntField("TaskType"), row.getStringField("CreatedDate"));
		addDataItem(row.getIntField("RowId"), row.getStringField("Value"), row.getStringField("TaskType"), row.getStringField("CreatedDate"));
	}while(select.nextRow());
	select.destroy();
}
// -------------------------------------------------------------------------
// Gets all data from databse and add to Grid.
int addGridDatas(int pStart, int pSize)
{
	int count = 1;
	// select all order by RowId
	SqlStatement select = dbProvider->sqlQuery("select RowId, Value, TaskType, CreatedDate from DataImEx order by RowId desc;");
	if(select.hasRow())
	{
		do
		{
			if(count > pStart && count < pStart + pSize + 1)
			{
				const SqlStatement::ResultRow& row = select.currentRow();
				//addDataItem(row.getIntField("RowId"), row.getFloatField("Value"), row.getIntField("TaskType"), row.getStringField("CreatedDate"));
				addDataItem(row.getIntField("RowId"), row.getStringField("Value"), row.getStringField("TaskType"), row.getStringField("CreatedDate"));
			}
			count++;
		}while(select.nextRow());
	}
	select.destroy();
	return --count;
}
// -------------------------------------------------------------------------
// Get last data from database and add to Grid.
void addGridLastData()
{
	// select last order by RowId
	SqlStatement select = dbProvider->sqlQuery("select RowId, Value, TaskType, CreatedDate from DataImEx order by RowId desc;");
	if(select.hasRow())
	{
		const SqlStatement::ResultRow& row = select.currentRow();
		addDataItem(row.getIntField("RowId"), row.getStringField("Value"), row.getStringField("TaskType"), row.getStringField("CreatedDate"));
	}
	select.destroy();
}
// -------------------------------------------------------------------------
void ClearData()
{
	CIwUIScrollableView* scrollableView = (CIwUIScrollableView*)dataGrid->GetElement();
	while(scrollableView->GetNumChildren() > 0)
	{
		CIwUIElement* child = scrollableView->GetChild(0);
		scrollableView->RemoveChild(child);
		delete child;
	}
}
// -------------------------------------------------------------------------
void ResetDataGrid(bool pLoadData)
{
	// Clear Data.
	ClearData();
	startItem = 0;
	itemCount = 0;
	if(pLoadData)
		itemCount = addGridDatas(startItem, pageSize);
	PreviousPage->SetEnabled(false);
	NextPage->SetEnabled(itemCount > pageSize);
}


// -------------------------------------------------------------------------
void insertData(const char* pValue, const char* pTaskType, const char* pCreatedDate)
{
	SqlStatement insert = dbProvider->sqlCompile("insert into DataImEx (Value, TaskType, CreatedDate) values (?, ?, ?);");
	insert.bind(pValue).bind(pTaskType).bind(pCreatedDate).execute();
	insert.destroy();
}
// -------------------------------------------------------------------------
// Update data of selected item (rowId) in Grid.
void updateData(const int pRowId, const char* pValue, const char* pTaskType, const char* pCreatedDate)
{
	SqlStatement update = dbProvider->sqlCompile("update DataImEx set Value = ?, TaskType = ?, CreatedDate = ? where RowId = ?;");
	update.bind(pValue).bind(pTaskType).bind(pCreatedDate).execute();
	update.destroy();
}
// -------------------------------------------------------------------------
// Delete data of selected item (rowId) in Grid.
void deleteData(const int pRowId)
{
	SqlStatement del = dbProvider->sqlCompile("delete from DataImEx where RowId = ?;");
	del.bind(pRowId).execute();
	del.destroy();
}
// -------------------------------------------------------------------------
// Delete all data in database
void deleteAllData()
{
	dbProvider->sqlExecute("delete from DataImEx;");
	//del.execute();
	//del.destroy();
}
// -------------------------------------------------------------------------
void writeDBData()
{
	char* str = new char[255];
	if(g_Task == Import)
		strcpy(str,"Import");
	else
		strcpy(str,"Export");

	time_t day = GetNow();
	char* title = new char[64];
    //strftime (title, 64, "%d %m %Y", localtime(&day));
    strftime (title, 64, "%A %d %b %Y", localtime(&day));

	// Insert Data to database.
	insertData(LabelInput->GetCaption(), str, title);

	delete[] str;
	delete[] title;
}


class CCommandHandler
{
public:
    CCommandHandler()
    {
        IW_UI_CREATE_VIEW_SLOT1(this, "CCommandHandler", CCommandHandler,
            OnClickQuit, CIwUIElement*);
        IW_UI_CREATE_VIEW_SLOT1(this, "CCommandHandler", CCommandHandler,
            OnClickReset, CIwUIElement*);
        IW_UI_CREATE_VIEW_SLOT1(this, "CCommandHandler", CCommandHandler,
            OnClickTask, CIwUIElement*);
        IW_UI_CREATE_VIEW_SLOT1(this, "CCommandHandler", CCommandHandler,
            OnClickAction, CIwUIElement*);
        IW_UI_CREATE_VIEW_SLOT1(this, "CCommandHandler", CCommandHandler,
            OnClickFunction, CIwUIElement*);
        IW_UI_CREATE_VIEW_SLOT1(this, "CCommandHandler", CCommandHandler,
            OnClickCancel, CIwUIElement*);
        IW_UI_CREATE_VIEW_SLOT1(this, "CCommandHandler", CCommandHandler,
            OnClickBack, CIwUIElement*);
        IW_UI_CREATE_VIEW_SLOT1(this, "CCommandHandler", CCommandHandler,
            OnClickEnter, CIwUIElement*);
        IW_UI_CREATE_VIEW_SLOT1(this, "CCommandHandler", CCommandHandler,
            OnPageNavigator, CIwUIElement*);
        IW_UI_CREATE_VIEW_SLOT1(this, "CCommandHandler", CCommandHandler,
            OnDeleteConfirm, CIwUIElement*);
    }

    ~CCommandHandler()
    {
        IW_UI_DESTROY_VIEW_SLOTS(this)
    }


	void OnClickTaskPublic(CIwUIElement* element)
	{
		OnClickTask(element);
	}
private:
    void OnClickQuit(CIwUIElement* element)
    {
			g_Quit = true;
    }
    void OnClickReset(CIwUIElement* element)
    {
		DeleteDialog->SetVisible(true);
		IwGetUIView()->SetModal(DeleteDialog);
	}
	void OnDeleteConfirm(CIwUIElement* element)
	{
		CIwUIButton* btn = (CIwUIButton*)element;
		if(!strcmp(btn->GetCaption(), "OK"))
		{
			m_MoneyImport = 0;
			m_MoneyExport = 0;
  			LabelMoneyIn->SetCaption("0");
  			LabelMoneyOut->SetCaption("0");
			LabelRemain->SetCaption("0");
			LabelInput->SetCaption("0");
			Button_Dot->SetEnabled(true);
  			// Write into data store.
			writeFileData();
			// Delete data in database.
			deleteAllData();
			//g_ClearData = true;
		}
		//ButtonReset->SetEnabled(false);
		DeleteDialog->SetVisible(false);
		IwGetUIView()->SetModal(NULL);
		//// Reset data grid.
		//ResetDataGrid(false);
	}
    void OnClickCancel(CIwUIElement* element)
    {
		LabelInput->SetCaption("0");
		Button_Dot->SetEnabled(true);
	}
    void OnClickBack(CIwUIElement* element)
    {
		CIwUIButton* btn = (CIwUIButton*)element;
		const char* lblInput = LabelInput->GetCaption();
		int len = strlen(lblInput);
		if(len == 1)
		{
			LabelInput->SetCaption("0");
			return;
		}
		char c = lblInput[len-1];
   		char* inputstr1 = new char[len];
		strncpy(inputstr1, lblInput, len);
		inputstr1[len - 1] = '\0';
		LabelInput->SetCaption(inputstr1);
		if(c == '.')
		{
			Button_Dot->SetEnabled(true);
		}
		delete[] inputstr1;
    }
	void OnClickEnter(CIwUIElement* element)
    {
		CIwUIButton* btn = (CIwUIButton*)element;
		const char* lblInput = LabelInput->GetCaption();
		double money = strtod(lblInput, NULL);
		if(money > 0)
		{
			CIwUILabel* LabelMoney;
			if(g_Task == Import)
			{
				m_MoneyImport += money;
				money = m_MoneyImport;
				LabelMoney = LabelMoneyIn;
			}
			else
			{
				m_MoneyExport += money;
				money = m_MoneyExport;
				LabelMoney = LabelMoneyOut;
			}
			char* sMoney = new char[100];
			sprintf(sMoney,"%1.2lf",money);
			removeRight(sMoney);
			LabelMoney->SetCaption(sMoney);
			sprintf(sMoney,"%1.2lf",m_MoneyImport - m_MoneyExport);
			removeRight(sMoney);
			LabelRemain->SetCaption(sMoney);
			delete sMoney;
			// Write into data store.
			writeFileData();
			// Write into database.
			writeDBData();
			//// Add last data from database to grid.
			//addGridLastData();
			// Reset dat grid,
			ResetDataGrid(true);
			//ButtonReset->SetEnabled(true);
		}
		// Reset Input.
		LabelInput->SetCaption("0");
		Button_Dot->SetEnabled(true);
	}
	void OnClickTask(CIwUIElement* element)
    {
		//char* textureName;
		//double money;
		if(element == TaskImport)
		{
			//money = m_MoneyImport;
			g_Task = Import;
			//textureName = "import";
			TaskImport->SetEnabled(false);
			TaskExport->SetEnabled(true);
		}
		else if(element == TaskExport)
		{
			//money = m_MoneyExport;
			g_Task = Export;
			//textureName = "export";
			TaskExport->SetEnabled(false);
			TaskImport->SetEnabled(true);
		}
		//char* sMoney = new char[100];
		//sprintf(sMoney,"%1.2lf",money);
		//removeRight(sMoney);
		//LabelMoney->SetCaption(sMoney);
		////CIwTexture* pTexture = (CIwTexture*)pResGroup->GetResNamed(textureName, "CIwTexture");
		////ImageMoney->SetTexture(pTexture);
		////delete[] textureName;
		//delete[] sMoney;
    }
    void OnClickAction(CIwUIElement* element)
    {
		const char* lblInput = LabelInput->GetCaption();
		if(strlen(lblInput) > 9)// Accept 10 number.
			return;
		const char* number = ((CIwUIButton*)element)->GetCaption();
		char* inputstr = new char[strlen(lblInput) + strlen(number)];
		// append string.
		strcpy(inputstr, lblInput);
		if(strcmp(lblInput, "0") || !strcmp(number, "."))//lblInput != "0"
		{
			strcat(inputstr, number);
			if(!strcmp(number, "."))
			{
				Button_Dot->SetEnabled(false);
			}
		}
		// replace string.
		else if(strcmp(number,"0") && strcmp(number, "00"))//number != "0" && number != "00"
		{
			strcpy(inputstr, number);
		}
		LabelInput->SetCaption(inputstr);
		delete[] inputstr;
   }
    void OnClickFunction(CIwUIElement* element)
    {
		if(element == TaskImport)
		{
			LabelRemain->SetCaption("Import");
		}
		else if(element == TaskExport)
		{
			LabelRemain->SetCaption("Export");
		}
    }
	void OnPageNavigator(CIwUIElement* element)
	{
		if(element == PreviousPage)
		{
			if(startItem > (pageSize -1))
			{
				startItem -= pageSize;
				if(startItem < 0)
					startItem = 0;
			}
		}
		else if(element == NextPage)
		{
			startItem += pageSize;
		}
		PreviousPage->SetEnabled(startItem > pageSize -1);
		NextPage->SetEnabled(startItem + pageSize < itemCount);
		// Clear Data.
		ClearData();
		// Add All Data from database.
		itemCount = addGridDatas(startItem, pageSize);
	}
};

// Standard C-style entry point. This can take args if required.
int main()
{
    IwGxInit();

    // Example main loop
    AppInit();
	
	//AppInstant = this;

    // Set screen clear colour
    IwGxSetColClear(0xff, 0xff, 0xff, 0xff);
    IwGxPrintSetColour(128, 128, 128);
    int64 start = s3eTimerGetMs();
    while (!g_Quit)
    {
        s3eDeviceYield(0);
        s3eKeyboardUpdate();
        s3ePointerUpdate();

		uint64 currentTime = s3eTimerGetMs();
        int32 updateTime = currentTime > start ?
            MIN((int32)(currentTime - start), 1000) : 0;
        start = currentTime;
        bool result = AppUpdate(updateTime);
        if  (
            (result == false) ||
            (s3eKeyboardGetState(s3eKeyEsc) & S3E_KEY_STATE_DOWN) ||
            (s3eKeyboardGetState(s3eKeyAbsBSK) & S3E_KEY_STATE_DOWN) ||
            (s3eDeviceCheckQuitRequest())
            )
            break;

        // Clear the screen
        IwGxClear(IW_GX_COLOUR_BUFFER_F | IW_GX_DEPTH_BUFFER_F);
        //RenderCursor();
        //RenderSoftkeys();
        AppRender();

        // Attempt frame rate
        while ((s3eTimerGetMs() - start) < MS_PER_FRAME)
        {
            int32 yield = (int32) (MS_PER_FRAME - (s3eTimerGetMs() - start));
            if (yield<0)
                break;
            s3eDeviceYield(yield);
        }
        
		// Check for quit request
        g_Quit |= (s3eDeviceCheckQuitRequest()!=0);
	}

    //delete g_CursorMaterial;
    AppShutDown();
    IwGxTerminate();
    return 0;
}


void InitComponent(const char* rootElementName)
{
	// singletons
	pCommandHandler = new CCommandHandler;

    //Find the dialog template
    rootElement = (CIwUIElement*)IwGetResManager()->GetResNamed(rootElementName, "CIwUIElement");
    if (!rootElement)
        return;

    //Remove the old screen
    if (rootElement)
        IwGetUIView()->DestroyElements();

    //And instantiate it
    rootElement = rootElement->Clone();
    IwGetUIView()->AddElement(rootElement);
    IwGetUIView()->AddElementToLayout(rootElement);
	// Add Delete Dialog.
	DeleteDialog = CIwUIElement::CreateFromResource("DeleteDialog");
	DeleteDialog->SetVisible(false);
	IwGetUIView()->AddElementToLayout(DeleteDialog);

	//ImageMoney = (CIwUIImage*)rootElement->GetChildNamed("TitlePanel")->GetChildNamed("ImageMoney");
	LabelMoneyIn = (CIwUILabel*)rootElement->GetChildNamed("TitlePanel")->GetChildNamed("LabelMoneyIn");
	LabelMoneyOut = (CIwUILabel*)rootElement->GetChildNamed("TitlePanel")->GetChildNamed("LabelMoneyOut");
	LabelRemain = (CIwUILabel*)rootElement->GetChildNamed("TitlePanel")->GetChildNamed("LabelRemain");
	LabelInput = (CIwUILabel*)rootElement->GetChildNamed("TaskPanel")->GetChildNamed("LabelInput");
	TaskImport = (CIwUIButton*)rootElement->GetChildNamed("TaskPanel")->GetChildNamed("TaskImport");
	TaskExport = (CIwUIButton*)rootElement->GetChildNamed("TaskPanel")->GetChildNamed("TaskExport");
	ButtonReset = (CIwUIButton*)rootElement->GetChildNamed("TaskPanel")->GetChildNamed("ButtonReset");
	Button_Dot = (CIwUIButton*)rootElement->GetChildNamed("ActionPanel")->GetChildNamed("Button_Dot");
	PreviousPage = (CIwUIButton*)rootElement->GetChildNamed("BottomPanel")->GetChildNamed("PreviousPage");
	NextPage = (CIwUIButton*)rootElement->GetChildNamed("BottomPanel")->GetChildNamed("NextPage");
	dataGrid = (CIwUILayoutGrid*)rootElement->GetChildNamed("TaskDetail")->GetChildNamed("scrollableView")->GetLayout();

	PreviousPage->SetEnabled(false);
	NextPage->SetEnabled(false);
	// read from data store.
	readFileData();

	if(g_Task == Import)
		pCommandHandler->OnClickTaskPublic(TaskImport);
	else if(g_Task == Export)
		pCommandHandler->OnClickTaskPublic(TaskExport);

	char* sMoneyTotal = dbtostr(m_MoneyImport - m_MoneyExport);
	LabelRemain->SetCaption(sMoneyTotal);
	delete[] sMoneyTotal;
	sMoneyTotal = dbtostr(m_MoneyImport);
	LabelMoneyIn->SetCaption(sMoneyTotal);
	delete[] sMoneyTotal;
	sMoneyTotal = dbtostr(m_MoneyExport);
	LabelMoneyOut->SetCaption(sMoneyTotal);
	delete[] sMoneyTotal;

	//showDate();
	// -------------------------------------------------------------------------
	// Sqlite.
	if (s3eFileCheckExists(DB_FILE_NAME) == S3E_TRUE)
	{
		//s3eFileDelete(DB_FILE_NAME);
		// Open or create the database:
		dbProvider = new SqlDatabase(DB_FILE_NAME, false);

		// -------------------------------------------------------------------------
		// Grid.
		// Create Grid with 4 columns.
		dataGrid->AddColumn();
		dataGrid->AddColumn();
		dataGrid->AddColumn();
		dataGrid->AddColumn();
		//// Create Grid Title.
		//CIwUILabel* firstName = createLabel("Value");
		//CIwUILabel* lastName = createLabel("Task type");
		//CIwUILabel* mobileName = createLabel("Date");
		//CIwUILabel* rowId = createLabel("RowId");
		//// Add Title to Grid.
		//dataGrid->AddRow();
		//int rowCount = 0; //dataGrid->GetNumRows();
		//dataGrid->AddElement(firstName, 0, rowCount);
		//dataGrid->AddElement(lastName, 1, rowCount);
		//dataGrid->AddElement(mobileName, 2, rowCount);
		//dataGrid->AddElement(rowId, 3, rowCount); rowId->SetVisible(false);

		// Add All Data from database.
		itemCount = addGridDatas(startItem, pageSize);
	}

}

void DestroyComponent()
{
	IwGetUIView()->DestroyElements();//delete rootElement;
	// Destroy singletons
    delete pCommandHandler;
}

//-----------------------------------------------------------------------------
void AppInit()
{
    //Initialise the IwUI module
    IwUIInit();

    //Instantiate the view and controller singletons.
    //IwUI will not instantiate these itself, since they can be subclassed to add functionality.
    new CIwUIController;
    new CIwUIView;

	//Load group which contains the ui specifications
    pResGroup = IwGetResManager()->LoadGroup("IncomeOutcome.group");

	////Set the default style sheet.			<Option>
	//CIwResource* pResource = IwGetResManager()->GetResNamed("iwui", IW_UI_RESTYPE_STYLESHEET);
	//IwGetUIStyleManager()->SetStylesheet(IwSafeCast<CIwUIStylesheet*>(pResource));

	//InitComponent("main");
	InitComponent(m_RootElement);

}
//-----------------------------------------------------------------------------
void AppShutDown()
{
	// Destroy Database Provider.
 	if(dbProvider)
	{
		dbProvider->close();
		delete dbProvider;
	}

   // Destroy resources
    IwGetResManager()->DestroyGroup(pResGroup);
	//IwResManagerTerminate();

	DestroyComponent();

    delete IwGetUIController();
    delete IwGetUIView();


    //Terminate the IwUI module
    IwUITerminate();
}
//-----------------------------------------------------------------------------
bool AppUpdate(int32 deltaMS)
{

    //Update the controller (this will generate control events etc.)
    IwGetUIController()->Update();

    //Update the view (this will do animations etc.) The example framework has
    //a fixed framerate of 20fps, so we pass that duration to the update function.
    //IwGetUIView()->Update(1000/20);
    IwGetUIView()->Update(deltaMS);

	//// Reset dat grid,
	//if(g_ClearData)
	//{
	//	ResetDataGrid(false);
	//	g_ClearData =  false;
	//}

    return true;
}
//-----------------------------------------------------------------------------
void AppRender()
{
    //Render the UI
    IwGetUIView()->Render();

    //Flush IwGx
    IwGxFlush();

    //Display the rendered frame
    IwGxSwapBuffers();
}


//-----------------------------------------------------------------------------
//void CController::OnClickButton(CIwUIElement* button)
//{
//CIwPropertyString pString;
//button->GetProperty("name", pString);
//if (strcmp(pString.c_str(), "btnExit") == 0)
//DoSomethingHere();
//}

//-----------------------------------------------------------------------------
class MyButtonEventHandler : public CIwUIElementEventHandler
{
public:
    //HandleEvent is passed up the element hierarchy
    virtual bool HandleEvent(CIwEvent* pEvent)
    {
        //if (pEvent->GetID() == IWUI_EVENT_BUTTON)
        //{
        //    char captionString[0x40];
        //    sprintf(captionString, "I have been\n clicked %i times",++s_ClickCounter);
        //    s_Button->SetCaption(captionString);

        //    //return true, as event has been handled
        //    return true;
        //}

        return false;
    }

    //FilterEvent is passed down the element hierarchy
    virtual bool FilterEvent(CIwEvent* pEvent)
    {
		//switch ( pEvent->GetID() )
		//{
		//case IWUI_EVENT_BUTTON:
		//{
		//CIwUIButton* pButton = ((CIwUIEventButton*)pEvent)->GetButton();
		//if ( pButton == (CIwUIButton*)IwGetUIView()->GetChildNamed("my_button") )
		//{
		//// Button named "my_button" was clicked
		//}
		//break;
		////return false, since filtering is not necessary
        return false;
    }
};

